//package com.yonyou.ucf.mdd.isv.service;
//
//import com.yonyou.ucf.mdd.ext.core.AppContext;
//import java.math.BigDecimal;
//import java.util.HashMap;
//import java.util.HashSet;
//import java.util.Map;
//import java.util.Map.Entry;
//import java.util.Set;
//import java.util.concurrent.TimeUnit;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.StringUtils;
//import org.imeta.spring.support.id.IdMagClient;
//import org.imeta.spring.support.id.IdManager;
//import org.springframework.data.redis.core.Cursor;
//import org.springframework.data.redis.core.ScanOptions;
//import org.springframework.data.redis.core.StringRedisTemplate;
//import org.springframework.scheduling.annotation.Scheduled;
//
//@Slf4j
//public class ISVIdManager implements IdMagClient {
//
//  private final static String COLON = ":";
//  private final static String SPLIT = "#";
//
//  private final static int SLEEP_TIME = 2 * 1000;
//  private final static int SCOPE_TIME = 5 * 1000;
//  private final static int TIMEOUT = 2 * 60 * 1000;
//  private final static int RENEW_TIME = 20 * 1000;
//
//  private long workerId;
//
//  private long dataCenterId;
//
//  private String domainUniId;
//
//  private String workerIdLastRegTime;
//
//  private StringRedisTemplate redisTemplate;
//
//
//  public Map<String, Long> getDynamicWorkIdAndDataCenterId(Long workerId, Long dataCenterId,
//      String domainUniId, long maxWorkerId, long maxDataCenterId) {
//    this.dataCenterId = dataCenterId;
//    this.domainUniId = domainUniId;
//    Map<String, Long> result = new HashMap<>();
//    if (redisTemplate == null){
//      redisTemplate = AppContext.getBean(StringRedisTemplate.class);
//    }
//    String prefixKey = getPrefixKey(domainUniId,dataCenterId);
//    getLock(prefixKey);
//    // 获取redis中已经使用的workerIdKey
//    Set<Long> workerIds = new HashSet<>();
//    BigDecimal sum = new BigDecimal(0);
//    Cursor<Entry<Object, Object>> scan = redisTemplate.opsForHash()
//        .scan(prefixKey, ScanOptions.scanOptions().match("*").count(maxWorkerId).build());
//    while (scan.hasNext()){
//      Entry<Object, Object> entry = scan.next();
//      // 获取redis中已经使用的workerId
//      String workerIdKey = (String) entry.getKey();
//      Long usedWorkerId = Long.valueOf(workerIdKey.split(SPLIT)[1]);
//      workerIds.add(usedWorkerId);
//      // 获取每个key对应的注册时间value
//      String lastRegTime = (String) entry.getValue();
//      // 每个key的剩余过期时间
//      Long expire = redisTemplate.getExpire(workerIdKey,TimeUnit.MILLISECONDS);
//      // 根据value得到其对应服务器的当前时间(lastRegTimne+(超时时间-剩余时间))
//      Long currentTime = Long.valueOf(lastRegTime) + TIMEOUT - expire;
//      sum.add(new BigDecimal(currentTime));
//    }
//    // 校验当前服务所在机器与其他服务的时间的差距
//    int size = workerIds.size();
//    if (size > 0){
//      Long avgTime = sum.divide(BigDecimal.valueOf(size),0,BigDecimal.ROUND_HALF_UP).longValue();
//      if (Math.abs(timeGen() - avgTime) > SCOPE_TIME){
//        log.error("The current server time is incorrect:the offset with other servers‘s average time is more than 5 seconds.");
//        unLock(prefixKey);
//        return result;
//      }
//    }
//    if (registerWorkId(domainUniId,dataCenterId,workerIds,maxWorkerId)){
//      result.put("workerId",this.workerId);
//      result.put("dataCenterId",this.dataCenterId);
//    } else {
//      log.error("Assign workId failed，because the full number[" + maxWorkerId + "] has been used");
//      unLock(prefixKey);
//    }
//    // 释放锁
//    unLock(prefixKey);
//    return result;
//  }
//
//  @Override
//  public boolean deleteExistNode(Long workerId, Long datacenterId, String domainUniId) {
//    String key = "";
//    try {
//      key = getWorkerIdKey(domainUniId,datacenterId,workerId);
//      redisTemplate.delete(key);
//      return true;
//    } catch (Exception e){
//      log.error("delete key {} false",key);
//      return false;
//    }
//  }
//
//  @Override
//  public void close() {
//
//  }
//
//  /**
//   * 根据domainUniId和dataCenterId生成的prefixKey
//   */
//  private String getPrefixKey(String domainUniId,Long dataCenterId){
//    return new StringBuilder()
//        .append("ISV")
//        .append(COLON)
//        .append(domainUniId)
//        .append(COLON)
//        .append(dataCenterId)
//        .toString();
//  }
//
//  /**
//   * 加分布式锁
//   */
//  private void getLock(String prefixKey){
//    while (!redisTemplate.opsForValue().setIfAbsent("lock:" + prefixKey,"value",TIMEOUT,TimeUnit.MILLISECONDS)){
//      try {
//        Thread.sleep(SLEEP_TIME);
//      } catch (InterruptedException e) {
//        e.printStackTrace();
//      }
//    }
//  }
//
//  /**
//   * 解锁
//   */
//  private void unLock(String prefixKey){
//    redisTemplate.delete("lock:" + prefixKey);
//  }
//
//  /**
//   * 获取当前系统时间
//   */
//  private long timeGen(){
//    return System.currentTimeMillis();
//  }
//
//
//  /**
//   * 分配workerId
//   */
//  private boolean registerWorkId(String domainUniId,Long dataCenterId,Set<Long> workerIds ,long maxWorkerId){
//    for (long workerId = 1; workerId < maxWorkerId;workerId++){
//      if (!workerIds.contains(workerId)){
//        String key = getWorkerIdKey(domainUniId,dataCenterId,workerId);
//        String currentTime = String.valueOf(timeGen());
//        redisTemplate.opsForValue().set(key, currentTime,TIMEOUT,TimeUnit.MILLISECONDS);
//        this.workerId = workerId;
//        this.workerIdLastRegTime = currentTime;
//        log.info("workerId register success," + key +":" + currentTime);
//        return true;
//      }
//    }
//    return false;
//  }
//
//
//  /**
//   * 根据domainUniId和datacenterId、workerId生成的WorkIdKey
//   */
//  private String getWorkerIdKey(String domainUniId,Long dataCenterId,Long workerId){
//    return new StringBuilder()
//        .append(getPrefixKey(domainUniId,dataCenterId))
//        .append(SPLIT)
//        .append(workerId)
//        .toString();
//  }
//
///*  *//**
//   * 每隔20秒去续租workerId,若redis中不存在该workerId,则重新注册。
//   *//*
//  @Scheduled(fixedDelay = RENEW_TIME)
//  private void renewWorkId(){
//    String key = getWorkerIdKey(this.domainUniId,this.dataCenterId,this.workerId);
//    String lastRegTime = String.valueOf(redisTemplate.opsForValue().get(key));
//    if (StringUtils.isNotBlank(lastRegTime)){
//      if (lastRegTime.equals(this.workerIdLastRegTime)){
//        String currentTime = String.valueOf(timeGen());
//        redisTemplate.opsForValue().set(key, currentTime,TIMEOUT,TimeUnit.MILLISECONDS);
//        this.workerIdLastRegTime = currentTime;
//        log.info("workerId renew success," + key +":" + currentTime);
//        return;
//      }
//    }
//    IdManager idManager = AppContext.getBean(IdManager.class);
//    idManager.refreshWorkeridAndDatacenterId(1L,this.dataCenterId,this.domainUniId);
//  }*/
//}
